﻿using UnityEngine;
using UnityEngine.Events;
using USClientKernel.Template;
using System;
using System.Collections.Generic;
using Game.Logic.Events;
using Common.Utils;

using GameEventType = Game.Logic.Events.GameEventType;
using EventHandler = Common.Utils.EventHandler;

namespace Game.Logic.Manager
{
    public delegate void GameEventHandler(GameEvent _event);

    public class GameEventManager : Singleton<GameEventManager>
    {
        private Dictionary<GameEventHandler, Subscriber> m_dictSubscriber;
        private Dictionary<GameEventType, List<GameEventHandler>> m_dictHandler;

        // 初始化
        protected override void Init()
        {
            m_dictSubscriber = new Dictionary<GameEventHandler, Subscriber>();
            m_dictHandler = new Dictionary<GameEventType, List<GameEventHandler>>();
        }


        /// <summary>
        /// 注册事件监听
        /// </summary>
        /// <param name="_eventType">事件类型</param>
        /// <param name="_handler">事件回调处理</param>
        /// <returns>是否注册事件成功</returns>
        public bool RegisterEventListener(GameEventType _eventType, GameEventHandler _handler)
        {
            if (m_dictSubscriber.TryGetValue(_handler, out Subscriber s))
            {
                s.Subscrib((int)_eventType);
            }
            else
            {
                s = Subscriber.Create((int)_eventType, HandleGameEvent);
                m_dictSubscriber.Add(_handler, s);
            }

            if (!m_dictHandler.TryGetValue(_eventType, out List<GameEventHandler> handlers))
            {
                handlers = new List<GameEventHandler>();
                m_dictHandler.Add(_eventType, handlers);
            }

            if (handlers.Contains(_handler))
            {
                return false;
            }

            handlers.Add(_handler);
            return true;
        }


        /// <summary>
        /// 注销事件监听
        /// </summary>
        /// <param name="_eventType">事件类型</param>
        /// <param name="_handler">事件回调处理</param>
        /// <returns>是否注销事件成功</returns>
        public bool UnregisterEventListener(GameEventType _eventType, GameEventHandler _handler)
        {
            if (!m_dictSubscriber.TryGetValue(_handler, out Subscriber s))
                return false;

            if (!m_dictHandler.TryGetValue(_eventType, out List<GameEventHandler> list))
                return false;

            if (!list.Contains(_handler))
                return false;

            list.Remove(_handler);
            s.Unsubscrib((int)_eventType);
            if (s.RefCount <= 0)
            {
                m_dictSubscriber.Remove(_handler);
            }
            return true;
        }


        /// <summary>
        /// 注销事件监听
        /// </summary>
        /// <param name="_event">事件</param>
        public void HandleGameEvent(BaseEvent _event)
        {
            GameEvent gameEvent = _event.Cast<GameEvent>();
            if (null == gameEvent) return;
            if (!m_dictHandler.TryGetValue(gameEvent.GameEventType, out List<GameEventHandler> handlers)) return;
            foreach(GameEventHandler handler in handlers)
            {
                handler.Invoke(gameEvent);
            }
        }


        /// <summary>
        /// 派发事件模版
        /// </summary>
        /// <param name="_eventType">事件类型</param>
        public void DispatchEvent(GameEvent _event)
        {
            Publisher.Publish(_event);
        }
    }
}
